package com.plumejob.executor.util;

import com.alibaba.fastjson.JSON;
import org.apache.http.*;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeaderElementIterator;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.Args;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.SSLContext;
import java.io.IOException;

public class HttpsClient {
    private static Logger logger = LoggerFactory.getLogger(HttpsClient.class);

    private static CloseableHttpClient httpclient = createSSLClientDefault();

    private static CloseableHttpClient createSSLClientDefault() {
            SSLContext sslcontext = SSLContexts.createDefault();
            SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1.2" },
                    null,SSLConnectionSocketFactory.getDefaultHostnameVerifier());

            Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                    .register("http", PlainConnectionSocketFactory.getSocketFactory())
                    .register("https", factory)  // 用来配置支持的协议
                    .build();
            // 加个共享连接池
            PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
            connectionManager.setMaxTotal(10);
            connectionManager.setDefaultMaxPerRoute(10);

            return HttpClients.custom()
                    .setConnectionManager(connectionManager)
                    .setSSLSocketFactory(factory)
                    .setConnectionManagerShared(true)
//                    .setDefaultRequestConfig(requestConfig)
                    .build();
    }

    public static String get(String url) {
        HttpGet httpGet = new HttpGet(url);
        httpGet.setHeader("Content-type", "application/x-www-form-urlencoded");
        CloseableHttpResponse response = null;
        String result = null;
        try {
            response = httpclient.execute(httpGet);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    result = EntityUtils.toString(resEntity, "utf-8");
                    return result;
                }
            }
        } catch (Exception e) {
            logger.error("请求URL= {} Get请求异常; StackTrace = {} ", url, e.getMessage());
            return null;
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    logger.error("关闭CloseableHttpResponse失败", e);
                }
            }
            if (httpclient != null) {
                try {
                    httpclient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    logger.error("关闭CloseableHttpClient失败", e);
                }
            }

        }
        return null;
    }

    public static Object post(String url, Object data) {
        HttpPost httpPost = new HttpPost(url);
        CloseableHttpResponse response = null;
        String result = null;
        try {
            StringEntity s = new StringEntity(JSON.toJSONString(data));
            s.setContentEncoding("UTF-8");
            s.setContentType("application/json");
            httpPost.setEntity(s);
            response = httpclient.execute(httpPost);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    result = EntityUtils.toString(resEntity, "utf-8");
                    return result;
                }
            }
        } catch (Exception e) {
            logger.error("请求URL= {} Post请求异常; StackTrace = {} ", url, e.getMessage());
            return null;
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    logger.error("关闭CloseableHttpResponse失败", e);
                }
            }
            if (httpclient != null) {
                try {
                    httpclient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    logger.error("关闭CloseableHttpClient失败", e);
                }
            }

        }
        return null;
    }

    static class MyConnectionKeepAliveStrategy implements ConnectionKeepAliveStrategy {

        @Override
        public long getKeepAliveDuration(final HttpResponse response, final HttpContext context) {
            Args.notNull(response, "HTTP response");
            final HeaderElementIterator it = new BasicHeaderElementIterator(
                    response.headerIterator(HTTP.CONN_KEEP_ALIVE));
            while (it.hasNext()) {
                final HeaderElement he = it.nextElement();
                final String param = he.getName();
                final String value = he.getValue();
                if (value != null && param.equalsIgnoreCase("timeout")) {
                    try {
                        return Long.parseLong(value) * 1000;
                    } catch(final NumberFormatException ignore) {
                    }
                }
            }
            //DefaultConnectionKeepAliveStrategy -1 也就是无限的
            return 20*1000;
        }

    }
}
